home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / basic / vbmake.exe / MM.BAS < prev    next >
BASIC Source File  |  1993-05-05  |  20KB  |  627 lines

  1. ' Billy Dennigan MBN International Systems Ltd          March 1993
  2. ' Compuserve ID 100014,2700
  3. ' Makefile Generator
  4. ' This program generates a simple makefile by copying the MS Basic .MAK file
  5. ' to a file usable by the NMAKE utility, with the appropriate dependencies
  6. ' and switches.
  7. ' If you find this program useful, please acknowledge by E-Mail
  8. ' Example .INI files are included for VBDOS and BC7
  9. ' These should be changed to suit your personal configuration
  10. ' MM /? for help
  11.  
  12. DECLARE SUB IncludeFiles (Filename$, OutFile%)
  13. DECLARE SUB LoadList (ListFile$, ObjList$(), NumObjs%)
  14. DECLARE SUB ReadIni (IniFile$, Options() AS ANY)
  15. DECLARE SUB ShowHelp ()
  16. DECLARE SUB Substitute (Change$, ObjList$())
  17. DECLARE FUNCTION CmdParam$ (Cmd$, name$)
  18. DECLARE FUNCTION GetValue$ (Num%, Ini() AS ANY)
  19. DECLARE FUNCTION RemoveExt$ (Filename$)
  20. DECLARE FUNCTION RemovePath$ (Filename$)
  21.  
  22. '============== one of these per entry in the .INI file ==============
  23. TYPE IniRec
  24.   Index AS INTEGER
  25.   Value AS STRING * 50
  26. END TYPE
  27.  
  28. CONST FALSE = 0, TRUE = NOT FALSE
  29. CONST NumOfSources = 128  ' max. number of sources for an EXE file
  30. CONST MaxIniLines = 128   ' max. number of entries in .INI file
  31. CONST NumSettings = 8     ' change this if you add any settings to DATA
  32.  
  33. REDIM ObjList$(NumOfSources)
  34. REDIM Inis(MaxIniLines) AS IniRec
  35.    
  36. PRINT
  37. PRINT "     Makefile Generator.    Version 2.0   Mar.1993"
  38. PRINT "     Billy Dennigan, MBN International Systems Ltd."
  39. PRINT
  40.  
  41. Cmd$ = COMMAND$
  42.  
  43. '========== HELP FACILITY ==========
  44. IF INSTR(Cmd$, "/?") THEN
  45.   CALL ShowHelp
  46.   END
  47. END IF
  48.  
  49. '========= get the target filename if necessary ============
  50. IF Cmd$ = "" THEN
  51.   PRINT "Target File :";
  52.   INPUT TargetFile$
  53. ELSE
  54.   TargetFile$ = Cmd$
  55. END IF
  56. IF LEN(TargetFile$) = 0 THEN END
  57.  
  58. '================ GET THE NAME OF THE .INI FILE ===================
  59. IniFile$ = "MM.INI"
  60. DO UNTIL LEN(DIR$(IniFile$))
  61.   PRINT "Cannot find MM Initialisation file "; IniFile$;
  62.   PRINT " Please enter new file spec: ";
  63.   INPUT IniFile$
  64.   IF LEN(IniFile$) = 0 THEN CLOSE : END
  65. LOOP
  66.  
  67. '============ LOAD DATA INTO ARRAY OF RECORDS inis() ==============
  68. CALL ReadIni(IniFile$, Inis())
  69.  
  70. 'truncate the extension from the target file if it was specified
  71. TargetFile$ = UCASE$(TargetFile$)
  72. TargetFile$ = RemoveExt$(TargetFile$)
  73.  
  74. MakeFile$ = TargetFile$                  ' Makefile to be generated
  75. RespFile$ = TargetFile$ + ".LNK"         ' response file for linker
  76. ListFile$ = TargetFile$ + ".MAK"         ' input list of required files
  77. Tab$ = CHR$(9)
  78.  
  79. '--- load in the list of Modules -----
  80. CALL LoadList(ListFile$, ObjList$(), NumObjs%)
  81.   
  82. MkeFile% = FREEFILE
  83. OPEN MakeFile$ FOR OUTPUT AS #MkeFile%         ' MakeFile
  84. LnkFile% = FREEFILE
  85. OPEN RespFile$ FOR OUTPUT AS #LnkFile%         ' Response file
  86. mmddyy$ = DATE$
  87. ddmmyy$ = MID$(DATE$, 4, 2) + "/" + LEFT$(DATE$, 2) + "/" + RIGHT$(DATE$, 2)
  88.  
  89. PRINT #MkeFile%, "# Makefile for "; TargetFile$
  90. PRINT #MkeFile%, "# Date written: "; ddmmyy$; " at "; LEFT$(TIME$, 5);
  91. PRINT #MkeFile%, " by Makefile Generator [MM] Version 1.10"
  92. PRINT #MkeFile%, "# .INI file used was "; IniFile$
  93. PRINT #MkeFile%, "# Billy Dennigan, MBN International Systems Ltd."
  94. PRINT #MkeFile%, "# Uses response file "; RespFile$; " for Linker"
  95. PRINT #MkeFile%, "#"
  96.  
  97. '------ compiler is Setting 1 -----
  98. DO
  99.   Tmp$ = GetValue$(1, Inis())
  100.   TmpLen% = LEN(Tmp$)
  101.   IF TmpLen% THEN Compiler$ = Tmp$
  102. LOOP WHILE TmpLen%
  103.  
  104. '------ linker is Setting 2 ------
  105. DO
  106.   Tmp$ = GetValue$(2, Inis())
  107.   TmpLen% = LEN(Tmp$)
  108.   IF TmpLen% THEN Linker$ = Tmp$
  109. LOOP WHILE TmpLen%
  110.  
  111. '--------- extract all the compiler flags (Setting 3) ---------
  112. DO
  113.   ThisFlag$ = GetValue$(3, Inis())
  114.   CompFlag$ = CompFlag$ + ThisFlag$
  115. LOOP WHILE LEN(ThisFlag$)
  116.  
  117. '--------- extract all the linker flags (Setting 4) -----------
  118. DO
  119.   ThisFlag$ = GetValue$(4, Inis())
  120.   LinkFlag$ = LinkFlag$ + ThisFlag$
  121. LOOP WHILE LEN(ThisFlag$)
  122.  
  123. '--------- get filename substitutions (Setting 6) ------------
  124. DO
  125.   Change$ = GetValue$(6, Inis())
  126.   IF LEN(Change$) = 0 THEN EXIT DO
  127.   CALL Substitute(Change$, ObjList$())
  128. LOOP
  129.  
  130.  
  131. '------ INCLUDEs is Setting 7 ------
  132. 'At this point, just determine whether or not the user wants INCLUDED files
  133. ' put into the dependencies list. Will process them later on.
  134. DO
  135.   Tmp$ = GetValue$(7, Inis())
  136.   TmpLen% = LEN(Tmp$)
  137.   IF TmpLen% THEN GetIncludes$ = UCASE$(Tmp$)
  138. LOOP WHILE TmpLen%
  139. IF INSTR(GetIncludes$, "TRUE") THEN GetIncludes% = -1
  140.  
  141.  
  142. '------ ObjDir is Setting 8 ------
  143. ' this can be used to specify a directory where all .OBJ files are to be put
  144. DO
  145.   Tmp$ = GetValue$(8, Inis())
  146.   TmpLen% = LEN(Tmp$)
  147.   IF TmpLen% THEN
  148.     ObjDir$ = UCASE$(Tmp$)
  149.     ObjDir% = TRUE
  150.   END IF
  151. LOOP WHILE TmpLen%
  152.  
  153. '----- format the path so that it can be used to make up a valid filename
  154. LastChar$ = RIGHT$(ObjDir$, 1)
  155. IF LastChar$ <> ":" AND LastChar$ <> "\" THEN ObjDir$ = ObjDir$ + "\"
  156.  
  157.  
  158.  
  159. PRINT #MkeFile%, "# Can change your source file and compilers,etc here:"
  160. PRINT #MkeFile%, ""
  161. PRINT #MkeFile%, "EXE = "; TargetFile$
  162. PRINT #MkeFile%, "COMPILE = "; Compiler$
  163. PRINT #MkeFile%, "LINK = "; Linker$
  164. PRINT #MkeFile%, "COMPFLAGS = "; CompFlag$
  165. PRINT #MkeFile%, "LINKFLAGS = "; LinkFlag$
  166. PRINT #MkeFile%,
  167. PRINT #MkeFile%, "ALL : $(EXE).EXE"
  168.  
  169. '=========== DEPENDENCIES FOR THE .OBJ FILE  (COMPILATION PHASE) ===========
  170. FOR i% = 1 TO NumObjs%
  171.   Filename$ = ObjList$(i%)
  172.   Stem$ = RemoveExt$(Filename$)
  173.   
  174.   '---------- If a path was specified for the .OBJ files ---------
  175.   IF ObjDir% THEN Stem$ = ObjDir$ + RemovePath$(Stem$)
  176.  
  177.   PRINT Filename$;
  178.   PRINT #MkeFile%, ""
  179.   PRINT #MkeFile%, Stem$; ".OBJ : ";
  180.   PRINT #MkeFile%, Filename$;
  181.   IF GetIncludes% THEN
  182.     '------ Find which files have been INCLUDEd in this one ------
  183.     Col% = POS(0): Row% = CSRLIN
  184.     COLOR 15
  185.     PRINT " Scanning...";
  186.     COLOR 7
  187.     CALL IncludeFiles(Filename$, MkeFile%)
  188.     LOCATE Row%, Col%: PRINT "            ";
  189.     LOCATE Row%, Col%
  190.   END IF
  191.   PRINT
  192.   
  193.   PRINT #MkeFile%,
  194.   PRINT #MkeFile%, Tab$; "$(COMPILE) $(COMPFLAGS) "; Filename$; " "; Stem$; ".OBJ ;"
  195.   
  196. NEXT i%
  197.  
  198.  
  199. '========== DEPENDENCIES FOR THE .EXE FILE i.e. THE LINK PHASE =============
  200. PRINT #MkeFile%, ""
  201. PRINT #MkeFile%, "$(EXE).EXE : ";
  202. FOR i% = 1 TO NumObjs%
  203.   ObjFile$ = RemoveExt$(ObjList$(i%)) + ".OBJ "
  204.  
  205.   IF ObjDir% THEN ObjFile$ = ObjDir$ + RemovePath$(ObjFile$)
  206.  
  207.   PRINT #MkeFile%, ObjFile$; " ";
  208. NEXT i%
  209.  
  210. '=============== THE .EXE IS ALSO DEPENDENT ON .LIB FILES ==================
  211. Lib$ = GetValue$(0, Inis())     ' reset internal pointers
  212. DO
  213.   Lib$ = GetValue$(5, Inis())
  214.   IF LEN(Lib$) THEN PRINT #MkeFile%, UCASE$(Lib$); " ";  ELSE EXIT DO
  215. LOOP
  216.  
  217. PRINT #MkeFile%, ""
  218.  
  219. PRINT #MkeFile%, Tab$; "$(LINK) $(LINKFLAGS) ";
  220. PRINT #MkeFile%, "@"; RespFile$
  221.  
  222.  
  223. '=============== GENERATE THE LINKER RESPONSE FILE ===================
  224. '--------------- DEAL WITH ALL NECESSARY .OBJ FILES ------------------
  225. FOR i% = 1 TO NumObjs%
  226.   ObjFile$ = RemoveExt$(ObjList$(i%)) + ".OBJ "
  227.  
  228.   '--- temporary: leave the OBJ files in current dir ----
  229.   IF ObjDir% THEN ObjFile$ = ObjDir$ + RemovePath$(ObjFile$)
  230.   
  231.   PRINT #LnkFile%, ObjFile$; " +"
  232. NEXT i%
  233. '--------------- TERMINATE THE LIST OF .OBJ FILES ---------------------
  234. PRINT #LnkFile%,
  235.  
  236. '--------------- SPECIFY THE NAME OF THE .EXE FILE --------------------
  237. PRINT #LnkFile%, TargetFile$; ".EXE"
  238.  
  239. '--------------- SPECIFY THE NAME OF THE .MAP FILE --------------------
  240. PRINT #LnkFile%, "NUL.MAP"
  241.  
  242. '--------------- GENERATE THE LIST OF LIBRARY FILES -------------------
  243. Lib$ = GetValue$(0, Inis())     ' reset internal pointers
  244. DO
  245.   PRINT "Libraries : ";
  246.   Lib$ = GetValue$(5, Inis())
  247.  
  248.   'when "LIB=;" is encountered, no more libraries are included.
  249.   SemiColon% = INSTR(Lib$, ";")
  250.   IF SemiColon% THEN
  251.     Lib$ = LEFT$(Lib$, SemiColon%)
  252.     IF Lib$ = ";" THEN PRINT : EXIT DO
  253.   END IF
  254.  
  255.   IF LEN(Lib$) = 0 THEN         ' if the .INI file has no more libs,
  256.     INPUT "", Lib$              ' then get one from the user
  257.   ELSE
  258.     PRINT Lib$; "+"             ' this is the lib read from the .INI file
  259.   END IF
  260.   IF LEN(Lib$) = 0 THEN E